/**
 * @author Da Mu
 * @version 0.1.0
 * @mail 317782199@qq.com
 */
import { Controller, Post, Get, Res, Body, Query, UseInterceptors, UseGuards, HttpCode, HttpStatus, UploadedFile, UploadedFiles, BadRequestException, NotFoundException } from '@nestjs/common';
import { ApiTags, ApiOperation } from '@nestjs/swagger';
import { AuthGuard } from '@nestjs/passport';
import { FileInterceptor, FilesInterceptor } from '@nestjs/platform-express';
import { TemplateApiRedisService } from './TemplateApiPlugService/TemplateApiRedis.service';
import { TemplateApiLoginJWTDto, TemplateApiDown, TemplateApiEmail, TemplateApiSavePlayerLocaDataDto } from './TemplateApi.dto';
import { TemplateApiService } from './TemplateApi.service';
import { diskStorage } from 'multer';
import { v4 as uuidv4 } from 'uuid';
import UploadsType from '../utils/uploads.type';
import * as jsonfile from 'jsonfile';
import * as path from 'path';
import { existsSync, writeFileSync, readFileSync } from 'fs';



@ApiTags('TemplateApi')
@Controller({
    path: 'temp_api',
    version: '1',
})
export class TemplateApiController {
    constructor(
        private readonly redis: TemplateApiRedisService,
        private readonly templateApiService: TemplateApiService
    ) {

    };

    @Get('jwt')
    @ApiOperation({
        summary: '模板-JWT-生成器',
        description:
            '模板-用来测试 JWT 生成器',
    })
    async JWT(@Body() body: any, @Res() res: any, @Query() query: TemplateApiLoginJWTDto): Promise<any> {
        const token = await this.templateApiService.JWT(query);

        res.send(token);
    };

    @UseGuards(AuthGuard('jwt'))
    @Post('jwt_validate')
    @ApiOperation({
        summary: '模板-JWT-验证器',
        description:
            '模板-用来测试 JWT 验证器',
    })
    async JWTValidate(@Body() body: any, @Query() query: TemplateApiLoginJWTDto, @Res() res: any): Promise<any> {
        res.send({
            code: HttpStatus.OK,
            message: 'token-测试验证通过'
        });
    };

    @Post('upload')
    @UseInterceptors(FileInterceptor('file', {
        storage: diskStorage({
            destination: 'static/uploads/files',
            filename: (req, file, callback) => {
                return callback(null, `${uuidv4()}${path.extname(file.originalname)}`);
            }
        }),
        fileFilter(req, file, callback) {
            // 文档类型上传
            UploadsType.File(file, (num: number) => {
                if (num) {
                    callback(null, true);
                } else {
                    callback(
                        new BadRequestException('只允许上传文档文件（PDF, DOC, DOCX, XLS, XLSX, TXT）'),
                        false,
                    );
                };
            });
        },
        limits: {
            fileSize: UploadsType.imageFileSize
        }
    }))
    @ApiOperation({
        summary: '模板-文件上传',
        description:
            '模板-用来测试文件上传',
    })
    async upload(@UploadedFile() file: Express.Multer.File, @Body() body: any, @Res() res: any): Promise<any> {
        console.log('file:', file);

        res.send({
            code: HttpStatus.OK,
            message: '文件上传成功'
        });
    };

    @Post('uploads')
    @UseInterceptors(FilesInterceptor('files', 3, {
        storage: diskStorage({
            destination: 'static/uploads/images',
            filename: (req, file, callback) => {
                return callback(null, `${uuidv4()}${path.extname(file.originalname)}`);
            }
        }),
        fileFilter(req, file, callback) {
            // 图片类型上传
            UploadsType.Image(file, (num: number) => {
                if (num) {
                    callback(null, true);
                } else {
                    return callback(
                        new BadRequestException('只允许上传图片文件（jpg, jpeg, png, gif）'),
                        false,
                    );
                };
            });
        },
        limits: {
            fileSize: UploadsType.fileFileSize
        }
    }))
    @ApiOperation({
        summary: '模板-多文件上传',
        description:
            '模板-用来测试多文件上传',
    })
    async uploads(@UploadedFiles() files: Array<Express.Multer.File>, @Body() body: any, @Res() res: any): Promise<any> {
        console.log('files:', files);

        res.send({
            code: HttpStatus.OK,
            message: '文件上传成功'
        });
    };

    @Get('download')
    // @HttpCode(HttpStatus.OK)
    @ApiOperation({
        summary: '模板-文件下载',
        description:
            '模板-用来测试文件下载',
    })
    async download(@Query() query: TemplateApiDown, @Res() res: any): Promise<any> {
        const filePath = path.join(process.cwd(), 'static/uploads/images', 'fdd56209-05b7-454f-b955-893c9b7064f6.jpg');
        if (!existsSync(filePath)) {
            throw new NotFoundException('file not found');
        };
        // res.download(filePath);
        res.sendFile(filePath);
    };

    @Get('svgcode')
    // @HttpCode(HttpStatus.OK)
    @ApiOperation({
        summary: '模板-svg图形验证码',
        description:
            '模板-用来测试 svg 图形验证码',
    })
    async svgcode(@Query() query: any, @Res() res: any): Promise<any> {
        const svgcode = await this.templateApiService.svgcode(query);

        // res.type('image/svg+xml');
        res.send(svgcode);
    };

    @Post('svgcode_validate')
    // @HttpCode(HttpStatus.OK)
    @ApiOperation({
        summary: '模板-svg图形验证码-验证器',
        description:
            '模板-用来测试 svg 图形验证码-验证器',
    })
    async svgcodevalidate(@Query() query: any, @Res() res: any): Promise<any> {
        const { code } = query;
        const svgcode = await this.templateApiService.svgcodevalidate(code);

        res.send(svgcode);
    };

    @Get('qr')
    // @HttpCode(HttpStatus.OK)
    @ApiOperation({
        summary: '模板-二维码',
        description:
            '模板-用来测试二维码',
    })
    async qr(@Query() query: any, @Res() res: any): Promise<any> {
        const qr = await this.templateApiService.qrcode(query);

        res.send(qr);
    };

    @Post('email')
    // @HttpCode(HttpStatus.OK)
    @ApiOperation({
        summary: '模板-svg图形验证码-验证器',
        description:
            '模板-用来测试 svg 图形验证码-验证器',
    })
    async mail(@Body() body: TemplateApiEmail, @Res() res: any): Promise<any> {
        const svgcode = await this.templateApiService.email(body);

        res.send(svgcode);
    };

    /** ----------------------------------- Game Controller ------------------------------------------- */

    @Get('game/startGame')
    // @HttpCode(HttpStatus.OK)
    @ApiOperation({
        summary: '模板-开始游戏/队列/任务/创建任务',
        description:
            '模板-开始游戏/队列/任务/创建任务',
    })
    async startGame(@Query() query: { playerUID: string }, @Res() res: any): Promise<any> {
        const data = await this.templateApiService.startGame(query);

        res.send(data);
    };

    @Post('game/savePlayerStatusDataService')
    // @HttpCode(HttpStatus.OK)
    @ApiOperation({
        summary: '模板-存储玩家状态数据',
        description:
            '模板-用来测试存储玩家状态数据',
    })
    async savePlayerStatusDataService(@Body() body: any, @Res() res: any): Promise<any> {
        const queue = await this.templateApiService.savePlayerStatusDataService(body);

        res.send(queue);
    };

    @Post('game/savePlayersInfoForFirst')
    // @HttpCode(HttpStatus.OK)
    @ApiOperation({
        summary: '模板-存储玩家定位数据',
        description:
            '模板-用来测试存储玩家定位数据',
    })
    async savePlayersInfoForFirst(@Body() body: TemplateApiSavePlayerLocaDataDto, @Res() res: any): Promise<any> {
        const queue = await this.templateApiService.savePlayersInfoForFirst(body);

        res.send(queue);
    };

    @Post('game/playersBuildingStatus')
    // @HttpCode(HttpStatus.OK)
    @ApiOperation({
        summary: '模板-玩家安全屋建造状态',
        description:
            '模板-用来测试玩家安全屋建造状态',
    })
    async playersBuildingStatus(@Body() body: { playerName?: string, playerUID: string, playerBuildProgress: boolean, playerBuild: number, type: string }, @Res() res: any): Promise<any> {
        const queue = await this.templateApiService.playersBuildingStatus(body);

        res.send(queue);
    };

    @Post('game/playersFoodStatus')
    // @HttpCode(HttpStatus.OK)
    @ApiOperation({
        summary: '模板-玩家食物状态',
        description:
            '模板-用来测试玩家食物状态',
    })
    async playersFoodStatus(@Body() body: { playerName?: string, playerUID: string, advocado: number, dinner: number, drink: number, type: string }, @Res() res: any): Promise<any> {
        const queue = await this.templateApiService.playersFoodStatus(body);

        res.send(queue);
    };

    @Post('game/playersIndustryStatus')
    // @HttpCode(HttpStatus.OK)
    @ApiOperation({
        summary: '模板-玩家采掘工业',
        description:
            '模板-用来测试玩家采掘工业',
    })
    async playersIndustryStatus(@Body() body: { playerName?: string, playerUID: string, wood?: number, stone?: number, type: string }, @Res() res: any): Promise<any> {
        const queue = await this.templateApiService.playersIndustryStatus(body);

        res.send(queue);
    };

    @Get('game/getUiStatusTipImageItem')
    // @HttpCode(HttpStatus.OK)
    @ApiOperation({
        summary: '模板-获取ui状态图片列表',
        description:
            '模板-用来测试获取ui状态图片列表',
    })
    async getUiStatusTipImageItem(@Query() query: any, @Res() res: any): Promise<any> {
        const queue = await this.templateApiService.getUiStatusTipImageItem();

        res.send(queue);
    };

    @Get('game/getAllGameCoordinate')
    // @HttpCode(HttpStatus.OK)
    @ApiOperation({
        summary: '模板-获取游戏所有元素坐标',
        description:
            '模板-用来测试获取游戏所有元素坐标',
    })
    async getAllGameCoordinate(@Query() query: any, @Res() res: any): Promise<any> {
        const queue = await this.templateApiService.getAllGameCoordinate(query);

        res.send(queue);
    };

    @Get('game/getUiCameraSwitchImageItem')
    // @HttpCode(HttpStatus.OK)
    @ApiOperation({
        summary: '模板-获取ui镜头切换图片列表',
        description:
            '模板-用来测试获取ui镜头切换图片列表',
    })
    async getUiCameraSwitchImageItem(@Query() query: any, @Res() res: any): Promise<any> {
        const queue = await this.templateApiService.getUiCameraSwitchImageItem();

        res.send(queue);
    };

    @Get('game/getUiBuildImageItem')
    // @HttpCode(HttpStatus.OK)
    @ApiOperation({
        summary: '模板-获取ui建造图片列表',
        description:
            '模板-用来测试获取ui建造图片列表',
    })
    async getUibuildImageItem(@Query() query: any, @Res() res: any): Promise<any> {
        const queue = await this.templateApiService.getUibuildImageItem();

        res.send(queue);
    };

    @Get('game/getUiBuildTimer')
    // @HttpCode(HttpStatus.OK)
    @ApiOperation({
        summary: '模板-获取ui建造定时任务',
        description:
            '模板-用来测试获取ui建造定时任务',
    })
    async getUiBuildTimer(@Query() query: { playerUID: string }, @Res() res: any): Promise<any> {
        const queue = await this.templateApiService.getUiBuildTimer(query);

        res.send(queue);
    };

    @Get('game/getUiStatusTimer')
    // @HttpCode(HttpStatus.OK)
    @ApiOperation({
        summary: '模板-获取ui状态定时',
        description:
            '模板-用来测试获取ui状态定时',
    })
    async getUiStatusTimer(@Query() query: any, @Res() res: any): Promise<any> {
        const queue = await this.templateApiService.getUiStatusTimer();

        res.send(queue);
    };

    @Get('game/getPlayerInitInfoDev')
    // @HttpCode(HttpStatus.OK)
    @ApiOperation({
        summary: '模板-获取玩家初始化数据信息',
        description:
            '模板-用来测试获取玩家初始化数据信息',
    })
    async getPlayerInitInfoDev(@Query() query: any, @Res() res: any): Promise<any> {
        const queue = await this.templateApiService.getPlayerInitInfoDev();

        res.send(queue);
    };

    @Get('game/getPlayerBuildingRemainingTime')
    // @HttpCode(HttpStatus.OK)
    @ApiOperation({
        summary: '模板-获取是否建造中的剩余时间',
        description:
            '模板-用来测试获取是否建造中的剩余时间',
    })
    async getPlayerBuildingRemainingTime(@Query() query: { playerUID: string }, @Res() res: any): Promise<any> {
        const queue = await this.templateApiService.getPlayerBuildingRemainingTime(query);

        res.send(queue);
    };

    @Get('game/getPlayerIndustryCount')
    // @HttpCode(HttpStatus.OK)
    @ApiOperation({
        summary: '模板-获取玩家采掘数量',
        description:
            '模板-用来测试获取玩家采掘数量',
    })
    async getPlayerIndustryCount(@Query() query: { playerUID: string }, @Res() res: any): Promise<any> {
        const queue = await this.templateApiService.getPlayerIndustryCount(query);

        res.send(queue);
    };

    @Get('game/getEnable3DSceneModels')
    // @HttpCode(HttpStatus.OK)
    @ApiOperation({
        summary: '模板-获取Enable3d场景模型',
        description:
            '模板-用来测试获取Enable3d场景模型',
    })
    async getEnable3DSceneModels(@Query() query: any, @Res() res: any): Promise<any> {
        const queue = await this.templateApiService.getEnable3DSceneModels();

        res.send(queue);
    };

    @Get('game/getRangeRandomDistribution')
    // @HttpCode(HttpStatus.OK)
    @ApiOperation({
        summary: '模板-获取Enable3d场景物资范围随机分布',
        description:
            '模板-用来测试获取Enable3d场景物资范围随机分布',
    })
    async getRangeRandomDistribution(@Query() query: { radius: number }, @Res() res: any): Promise<any> {
        const queue = await this.templateApiService.getRangeRandomDistribution(query);

        res.send(queue);
    };

    @Post('game/playersPickUpMaterials')
    // @HttpCode(HttpStatus.OK)
    @ApiOperation({
        summary: '模板-Enable3d场景拾取物资',
        description:
            '模板-用来测试Enable3d场景拾取物资',
    })
    async playersPickUpMaterials(@Body() body: { type: string, playerUID: string }, @Res() res: any): Promise<any> {
        const json = await this.templateApiService.playersPickUpMaterials(body);

        res.send(json);
    };

    @Post('game/playersEatFood')
    // @HttpCode(HttpStatus.OK)
    @ApiOperation({
        summary: '模板-Enable3d场景食用食物',
        description:
            '模板-用来测试Enable3d场景食用食物',
    })
    async playersEatFood(@Body() body: { type: string, playerUID: string }, @Res() res: any): Promise<any> {
        const json = await this.templateApiService.playersEatFood(body);

        res.send(json);
    };

    @Get('game/backpack')
    // @HttpCode(HttpStatus.OK)
    @ApiOperation({
        summary: '模板-获取背包物品',
        description:
            '模板-用来测试获取背包物品',
    })
    async getBackpackItems(@Query() query: { playerUID: string }, @Res() res: any): Promise<any> {
        const json = await this.templateApiService.getBackpackItems(query);

        res.send(json);
    };


};